home *** CD-ROM | disk | FTP | other *** search
/ BMUG Revelations / BMUG Revelations.toast / Programming / Programming Languages / Yerk 3.64 / System source / Class < prev    next >
Text File  |  1993-06-07  |  18KB  |  600 lines

  1. \ Class/Object general properties and compilation code
  2. \  4/26/84  CBD Version 1.0
  3. \  4/26/84  CBD Speeded up ^Elem and friends
  4. \  4/27/84  CBD Moved rect, etc. to QD  file
  5. \  5/02/84  CBD Removed IX-non-IX restriction
  6. \  5/24/84  NDI Remove selector numbering, add objlen
  7. \  5/26/84  CBD Took non-class stuff out
  8. \  5/28/84  CBD Selectors defer refs to input parm objects
  9. \ 10/04/84  CBD Added class initialization, text messages
  10. \ 10/11/84  CBD objPtr and objArray support
  11. \ 10/12/84  CBD Added GET: and PUT: for arrays
  12. \ 10/18/84  CBD converted to mcfa Values
  13. \ 10/30/84  CBD propagate classInit: thru Ivar chains at create
  14. \ 11/02/84  CBD objects have executable CFA
  15. \ 11/02/84  CBD update for optimized array support in nucleus
  16. \ 11/16/84  CBD removed objArray, etc.
  17. \ 12/08/84  CBD ß1.0 version
  18. \ 12/14/84  cbd removed read:, write:, etc
  19. \ 12/15/84  cbd hashed selectors
  20. \ 12/12/85  cdn Put CR after redefined message in :M
  21. \  8/01/86  cdn Added "Method redefined, within same class ****" message
  22. \ 12/27/89    rfl    changed ?isclass to check for valid ram for @
  23. \  1/11/90    rfl    need to change traverse or at least ?cfa in nuc to protect for valid ram
  24. \ 11/23/90    rfl    Method redefined message now comes before selector for readability
  25. \ 12/17/90    rfl    added class name to above
  26. \  6/01/91    rfl    ovblock modified for sys 7...heap is below 0;
  27. \ 12/12/92    rfl 32 bit hash for methods; move ?rdepth to this source
  28. \ 12/25/92    rfl    changed nuc to set heapBot, heapTop in relative addr space
  29. \ 12/26/92    rfl object name not unique error gives name of object
  30. \  5/28/93    rfl    added within and used it in (@)
  31. \  6/04/93    rfl    modified (build) for source documentation (line#..)
  32.  
  33. 0 value (rdepth)
  34. : +rdepth 1 -> (rdepth) ;
  35. : -rdepth 0 -> (rdepth) ;
  36. : ?Rdepth (rdepth) IF  rdepth  220 > ?error 116 THEN ;
  37.  
  38. : +docs true -> docs ;
  39. : -docs false -> docs ;
  40.  
  41. : ^CLASS   current  @ pfa ;
  42.  
  43. \ the following offsets refer to the ^class, or Pfa of the class.
  44. : MFA    10 + ;    \ methods dictionary Latest field
  45. : IFA    14 + ;    \ ivar dict Latest field
  46. : DFA    18 + ;    \ Datalen , width of indexed area
  47. : SFA    22 + ;    \ superclass ptr field
  48.  
  49. \ Get length of object's named ivars
  50. : @DLEN cfa @ Dfa  W@   ;
  51.  
  52. \ ( SelPfa ^class -- m1cfa )  Find a method in a class
  53. : (FINDM)
  54.     swap over mfa ((findm))  0=
  55.     IF  cr msg# 108  nfa .name
  56.         abort
  57.     ELSE  swap drop THEN ;
  58.  
  59. \ ( Selhash objPfa -- objPfa m1cfa )
  60. \  Find a method 1cfa given a selector ID
  61. : FIND-METHOD
  62.     dup 0= ?error 103
  63.     swap over CFA @ (FINDM)  ;
  64.  
  65. \ ( objAddr -- )  Look up SelID at IP and run the method
  66. : (Defer)
  67.     w@(ip)    \ objPfa  selID
  68.     Swap  Find-Method Cfa    \ objAddr m0cfa
  69.     execute  ;    \ exec the  m0cfa
  70.  
  71.    0 Value  ^Self
  72.    0 Value  ^Super        \ nfa of SUPER pseudo-Ivar
  73.    0 Value  newObject    \ object being created
  74.    1 Value  rangeCheck    \ true if runtime range check desired
  75. true Value dEcho        \ echo load to screen?
  76.  
  77. 0 -> quitvec    \ clear vectors
  78. 0 -> abortvec
  79. 0 -> objInit
  80. 'c pfind -> ufind
  81.  
  82. \ ( addr -- hashVal )  hash a  name into a 16-bit word
  83. : Hash { addr -- }
  84.     0 addr count +  addr
  85.     DO 4* Dup 65535 > IF 1+ THEN
  86.         I  C@ 32 - xor  65535 And
  87.     LOOP ;
  88.  
  89. : within { n lo hi -- b } n lo >= n hi <= and ;
  90.  
  91. \ check to make sure the memory addressed is within the application heap zone
  92. : (@) ( addr -- n t or f)  dup heapBot heapTop within
  93.     IF @ true ELSE drop false THEN ;
  94.  
  95. \ ( pfa -- pfa b )  returns true if a class -  make sure pfa points within appl
  96. : ?IsClass  'CODE DoClass OVER CFA (@) IF = ELSE drop false THEN ;
  97.  
  98. \ ( pfa -- pfa b )  return true if an object
  99. :f ?IsObj
  100.     ?IsClass
  101.     IF  False
  102.     ELSE Dup cfa (@)
  103.         IF ?IsClass swap drop ELSE false THEN 
  104.     THEN ;f
  105.  
  106. \ ( pfa -- pfa b )  return true if an object vector
  107. : ?IsVect  dup cfa (@) IF  valCode = over cfa @ vectCode = or ELSE false THEN ;
  108.  
  109. \ ( pfa -- pfa b )  is ref'd word an open bracket?
  110. : ?IsParen  dup nfa 1+ c@ ascii [ =  ;
  111.  
  112. \ ( -- )  ERROR if not compiling a new class definition
  113. : ?Class   Cstate   0=  ?error 115  ;
  114.  
  115. \ ( classIFA -- f OR 1cfa t )  search CLASS dictionaries
  116. : ivarFind   here hash swap ((findm))   ;
  117.  
  118. \ ( -- f OR pfa t )  Determine if  next word is an instance var
  119. : vFind
  120.     bl word  Cstate
  121.     IF    \ class compile?
  122.         ^class  IFA ivarFind    \ search IVAR chain
  123.     ELSE  0 THEN ;    \ leave ff
  124.  
  125. \ Key to instantiation actions
  126. \ notFnd    -not previously defined
  127. \ objTyp    -defined as an object
  128. \ classTyp    -as a class
  129. \ vecTyp    -as an object vector- ptr, array, etc
  130. \ parmTyp    -as a named parm
  131. \ parenType    -open paren for defer group
  132.  
  133. \ ( #elems ^class  OR ^class -- indlen )
  134. : IDX-HDR   DFA 2+ W@ DUP IF  2DUP W, W,  * align THEN ;
  135.  
  136. \ ( IVnfa -- ivlfa )
  137. : ilfa   2+ ;
  138.  
  139. \ ( ilfa -- icfa )
  140. : ^ICLASS  CFALEN + @ ;
  141.  
  142. \ ( ^class -- elWidth )  return the indexed element width for class
  143. : @width   dfa 2+ w@  ;
  144.  
  145. \ ( infa -- icfa )  transform ivar nfa to its class field
  146. : icfa  ilfa  4+  ;
  147.  
  148. \ ( ivarlfa -- #els  wid  idxOffs  tf OR ff )
  149.  
  150. \ ( ivarNfa -- IvarNfa b )  True if nfa is Super or Self
  151. : ?LastIvar         Dup  ^Self   = Over ^Super   = OR ;
  152.  
  153. \ InitIvar  performs the classInit: method on the ivar on the stack )
  154. Forward InitIvar
  155.  
  156. \ ( ivarNfa -- latestNfa )  -> Latest nested Ivar
  157. : ^LatestIvar    ilfa ^Iclass  IFA  @  ;
  158. : ^NextIvar      ILFA  @ ;
  159.  
  160. \ ( ivarnfa -- ivoffs )  Return ivar's offset
  161. : @IvarOffs  ILFA  8+ W@  ;
  162.  
  163. \ ( ivarNfa -- IvarNfa newNfa t  OR  ivarNfa f )
  164. : ?Nest
  165.     Dup ^LatestIvar  ?LastIvar
  166.     IF  Drop 0 ELSE 1 THEN ;
  167.  
  168. \ ITRAV traverses the tree of nested ivar definitions in a
  169. \ class, building necessary indexed area headers
  170. \ the Mstack has the base offset for nested Ivars
  171. \ ( ivarNfa -- )
  172. : ITRAV
  173.     BEGIN  ?Rdepth ?Nest
  174.         IF Over @IvarOffs Dupm Addm Itrav THEN
  175.         Dup
  176.         ILFA dup    \ DO-NODE - Build header if indexed ivar
  177.         pushm copym ^iclass -dup    \ HDR-INFO
  178.         IF  copym $ 0a + w@  popm 8+ w@   ( #els  offs )
  179.             rot dup dfa w@ rot + swap @width  ( #els truoffs wdth)
  180.             swap over -dup
  181.             IF ELSE 2drop drop 0 THEN
  182.         ELSE  dropm 0 THEN    \ not idx
  183.         IF  CopyM +    \ add in nested base offset
  184.             pushm copym newObject  + w!   ( ! el-width )
  185.             popm  newObject  +  2+ W!  ( !  # els )
  186.             dup 4+ @        \ get ^class of indexed Ivar
  187.             over 8+ w@        \ get offs this ivar
  188.             copym  newObject + + cfa !    \ store in cfa
  189.         THEN  initIvar
  190.         ^NextIvar  ?LastIvar  Not
  191.     WHILE  REPEAT
  192.     DROP DropM ;
  193.  
  194. Forward  ClassInit
  195.  
  196. \ ( #elems ^class OR ^class -- ) Compile an instance variable dictionary entry
  197. : <VAR
  198.     pushm    \ place ^class on methods stack for later
  199.     Vfind  ?error 117
  200.     here dup hash w,        \ compile hashed ivar name into dict
  201.     ^Class IFA dup @ ,  !  COPYM  ,  ( link, class )
  202.     copym @width
  203.     IF  4 ^class dfa w+! THEN    \ if indexed, save 4 for cfa
  204.     ^Class DFA  W@  W,            \  ( current dLen= offset )
  205.     copym @width dup
  206.     IF over * swap W, 4+ THEN  ( #elems)
  207.     popM DFA W@  +  align    \ Account for named ivar lengths
  208.     ^Class  DFA   W+!   ;
  209.  
  210. \ ( -- )  Create hdr for the name at Here
  211. : CreateHdr
  212.     Here 1+ c@ 0= ?error 118
  213.     $ 80 S, latest , current !  0,   ;
  214.  
  215. \ ( m1cfa n -- )  Execute the ncfa of word on stack
  216. \ takes a standard Pfa = 1cfa as input
  217. \ : mExec  clen * swap 4- + Execute ;
  218.  
  219. \ ( #elems ^class OR ^class -- )  Build an instance of a class
  220. : (BUILD)
  221.     Pushm  Cstate
  222.     IF  Popm  <Var    \ build an ivar
  223.     ELSE
  224.         \ NEWTOKEN : pulls name from stream
  225.         Here 1 and IF 0 c, THEN docs IF line# w, THEN Find
  226.         IF drop ?isVect
  227.             IF  3 ( vecTyp )
  228.             ELSE  1 ( objTyp )
  229.             THEN
  230.         ELSE 0 ( notFnd ) THEN    ( -- pfa type OR 0 )
  231.  
  232.         \ OBJHDR :
  233.         \ Build a public  object header or just a cfa if headerless
  234.         \ If an object vector, load pfa of object into vector
  235.         \ ( {vectPfa} objType -- )  HERE is left at pfa of new object
  236.         Select{    \ on object type
  237.             0 ( notFnd )    Is{  CreateHdr  }End    \ not redefined
  238.  
  239.             1 ( objTyp )    Is{  drop createHdr
  240.                 type# 181 ( Object name not unique ) latest id.  cr   }End
  241.  
  242.             2 ( classtyp )  Is{ abort }End        \ should not get this
  243.  
  244.             \ ( ind vecPfa -- )  for object vectors, execute -> code at 2cfa
  245.             3 ( vecTyp )   Is{  0, Here  swap 2 clen * swap 4- + Execute
  246.                 msg# 120  }End
  247.  
  248.         Default{ abort }Select
  249.  
  250.         Here  -> newObject
  251.         Copym here  cLen - !    \ store ^class
  252.         copym  DFA  W@            ( dfa datalen )
  253.         Reserve        \ allocate named instances
  254.         copym  IDX-HDR  reserve
  255.         popm IFA @  ?LastIVar not
  256.         IF  0 Pushm Itrav ELSE drop THEN
  257.         classInit
  258.     THEN  ;
  259.  
  260. \ yerk grow zone function
  261. 'c null vect growZone
  262.  
  263. \ ( size -- addr )  acquire a block of nonrelocatable heap
  264. : ovBlock { size -- addr }
  265.     size  newPtr  dup +base 0=
  266.     IF  drop growZone  size newPtr dup +base 0=
  267.         ?error 121
  268.     THEN ;
  269.  
  270. \ build a new object on the heap for class. Use: Heap> className
  271. \ gets heap, and returns  relative  ptr
  272. : (heapObj) { theClass \ dLen obAddr idWid #els -- } 0 -> #els
  273.     theClass dfa w@ -> dlen  theClass dfa 2+ w@ -> idWid
  274.     idWid  IF -> #els THEN
  275.     dLen 4+ idWid IF  idWid #els * 4+ + THEN    \ get total length of obj
  276.     ovBlock  4+ -> obAddr    \ get nonReloc heap, save ptr to cfa
  277.     theClass obAddr cfa !    \ create the class ptr
  278.     idWid  IF  idWid  obAddr dLen + w!  #els obAddr dLen + 2+ w! THEN
  279.     obAddr -> newObject  theClass ifa @  ?LastIvar not
  280.     IF 0 PushM Itrav ELSE Drop THEN classinit obAddr   ;
  281.  
  282. : heap>
  283.     @pfa ?isClass not ?error 122
  284.     state
  285.     IF  Compile lit  ,
  286.         Compile (heapObj) ELSE (heapObj)
  287.     THEN
  288. ; Immediate
  289.  
  290. \ ( -- )  Set CSTATE to compiling a class
  291. : ]C  1 -> Cstate ; Immediate
  292. : C[  0 -> Cstate ; Immediate
  293.  
  294. \ compile hashed word for name at Here
  295. : hash,  @word hash w,  ;
  296.  
  297. $ 81FE0000 variable  aName  0 W,    \ fake name/link
  298.  
  299. \ ( -- )  The super class of Object - top of all inheritance
  300. : Meta
  301.     <[  'Code doClass ^Class CFA !
  302.     here 10 allot  'code objmp swap 10 cmove    \ jump to object code
  303.     aName ,        \ latest method pointer
  304.     0,            \ latest ivar pointer -> SUPER
  305.     0,   ( data len, flags)
  306.     0,   ( super pointer)  HERE -> ^SELF
  307.     hash, SELF    \ SELF ivar
  308.     0, 0, 65535 W,     ( link, ^class, offset)
  309.     Here  -> ^Super    \ save this address for later
  310.     hash, SUPER
  311.     ^self , 0, 65535 W,   ( link, ^class, offset )
  312.  
  313. ^super ' meta ifa !
  314.  
  315. \ ( -- )  Build a class header with its superclass pointer
  316. : <Super
  317.     @pfa dup        \ find the superclass
  318.     dup  ^Super icfa !    \ store superclass in SUPER
  319.     CFA here CFA    \ Set up for cmove to sub class
  320.     26 Cmove        \ create image of superclass header
  321.     ^Class SFA !    \ store superclass pointer
  322.     ^Class  ^Self icfa !    \ store ^class in SELF's icfa
  323.     26 allot
  324.     [Compile]  ]C [Compile]   <[    \ in class, interpret
  325. ; Immediate
  326.  
  327. 'c copym Vect caller    \ late bound reference to calling object
  328.  
  329. \ ( -- b )  true if word at Here is a selector xxx:
  330. : ?isSel  here count 1- + c@ ascii :  =  here c@ 1 > And ;
  331.  
  332. \ get a selector from the input stream
  333. : getSelect
  334.     @word dup c@ 15 >
  335.     ?error 123
  336.     ?isSel 0= ?error 124
  337.     hash  ;
  338.  
  339. \ ( -- )  Build a methods dictionary entry for selector
  340. : :M { \ selID -- }
  341.     ?Class  !Csp  [Compile] ]>
  342.     getSelect -> selID
  343.     selID ^class mfa ((findm))    \ is method already defined?
  344.     IF  type# 182 here count type  ( Method redefined )
  345.         space latest id.            \ add class name
  346.         ^class > IF type# 183 ( , within same class **** ) THEN cr
  347.     THEN
  348.     here  selID w,        \ name is selector's hashed value
  349.     ^class mfa dup @    \ get  mfa, old link
  350.     ,  !    \ establish the links
  351.     \ build methods cfas
  352.     'Code  M0CFA ,  'Code M1CFA ,
  353. ; Immediate
  354.  
  355. \ ( -- pfa tokenID )  Determine type of token referenced by selector.
  356. : refToken
  357.     uFind    \ look for named stack parm
  358.     IF  drop  4 ( parmTyp )
  359.     ELSE  here latest (find)  0=
  360.         ?error 125  drop  ?IsClass
  361.         IF  2 ( classTyp )
  362.         ELSE  ?IsVect
  363.             IF  3 ( vecTyp )
  364.             ELSE  ?IsObj
  365.                 IF  1 ( objTyp )
  366.                 ELSE  ?IsParen
  367.                     IF  5 ( parenType )
  368.                     ELSE  1 ?error 126
  369.                     THEN
  370.                 THEN
  371.             THEN
  372.         THEN
  373.     THEN  ;
  374.  
  375. \ ( objpfa -- a:datalen )
  376. : ^dlen   cfa @ dfa ;
  377.  
  378. \ ( ivarPfa  m1cfa )  compile an Ivar reference
  379. : ivar,    ,   w@ w,   ;    \ | 1cfa | offs |
  380.  
  381. \ ( objPfa  m0cfa )  compile an object ref
  382. : obj,   swap cfa , ,  ;    \ | objCfa | m0cfa |
  383.  
  384. \ ( selID ivPFa )
  385. : ivarRef    Find-Method ivar,   ;
  386.  
  387. \ ( selID -- )  Build a reference to an object or vector
  388. : objRef  refToken
  389.     SELECT{
  390.         0 ( notFnd )    IS{   abort  }END
  391.  
  392.         ( selID objPfa -- )
  393.         1 ( objTyp )    IS{ cfa execute
  394.             Find-Method cfa obj,   }END    \ normal obj ref
  395.  
  396.         2 ( classTyp )  IS{   (FINDM) cfa ,  }END    \ compile m0cfa
  397.  
  398.         ( selPfa  vecPfa -- )
  399.         3 ( vecTyp )    IS{  cfa , Compile (defer) w,  }END
  400.  
  401.         4 ( parmTyp )   IS{  cfa  ,    \ named parm- compile the pickCfa
  402.             Compile (Defer) W, }END    \ auto deferred
  403.  
  404.         5 ( parenType ) IS{  drop pushM  251   }END    \ paren'd defer group
  405.  
  406.     DEFAULT{  abort
  407.     }SELECT  ;
  408.  
  409. \ ( selPfa -- )  Execute using token in stream
  410. : runRef
  411.     @Pfa  drop  refToken
  412.     Select{
  413.         0 ( notFnd )     Is{  abort   }End
  414.         1 ( objTyp )     Is{  cfa execute  Find-Method    }End
  415.         2 ( classTyp )   Is{  (Findm)    }End
  416.  
  417.         ( selID  vecPfa -- )
  418.         3 ( vecTyp )     Is{  cfa execute  Find-Method    }End
  419.  
  420.         4 ( parmTyp )    Is{ abort    }End
  421.  
  422.         \ open bracket denotes a deferred ref to what
  423.         \ the paren'd group puts on the stack at runtime
  424.         5 ( parenType )  Is{  drop  Pushm ' null  }End
  425.  
  426.     Default{ abort
  427.     }Select  cfa  execute ;    \ execute the object, m0cfa
  428.  
  429. \ ================= Selector support ==========================
  430. \ message is the message compiler invoked by using a selector
  431. : message
  432.     state
  433.     IF    \ Compile state
  434.         VFIND    \ instance variable?
  435.         IF   ivarRef    \ ivar reference
  436.         ELSE   objRef    \ compile object/vector reference
  437.         THEN
  438.     ELSE runRef    \ run state - execute object/vector ref
  439.     THEN
  440. ; Immediate
  441.  
  442. \ if parsed word is a message selector, leave cfa of message compiler
  443. \ ( -- selID msgPfa 0 t OR f )
  444. : msgFind
  445.     ?isSel
  446.     IF  Here hash    \ leave selID
  447.         ' message $ c1 true
  448.     ELSE  pfind        \ look for named parms
  449.     THEN   ;
  450.  
  451. 'c msgFind -> Ufind
  452.  
  453. \ Force late binding of method to object, as in SmallTalk
  454. \ a close bracket pops the last selID from the methods stack and
  455. \ compiles a defer: selID.  This will build a deferred reference to the
  456. \ parenthesized group.
  457. : ]    State
  458.     IF  251 ?Pairs  Compile (Defer)
  459.         mdepth 0= ?error 127
  460.         popM   W,    \ Compile | {defer} |SelPfa|
  461.     ELSE  popM  Swap   Find-Method Cfa    \ exec state
  462.         execute
  463.     THEN
  464. ; Immediate
  465.  
  466. \ left bracket has no meaning unless preceded by a selector.
  467. : [  true ?error 128  ; Immediate
  468.  
  469. : ;M   ?Csp  Compile  (;M)   ;  Immediate
  470.  
  471. \ Leave class compilation state, and zero the class ptrs of Self and Super
  472. : ;Class  [Compile] <[  [Compile] C[
  473.         0  ^Super icfa !   0 ^Self icfa !  ;  Immediate
  474.  
  475. : :Class    [Compile] :    ; Immediate
  476.  
  477. \ ( width -- )  Set a class and its subclasses to indexed
  478. : <Indexed  ?class ^class DFA 2+ W! ;
  479.  
  480. \ ( dim -- )  Set an indexed class to a multi-dimensionality
  481. \ : <Dim
  482. \    ?class ^class DFA 2+ W@ 0= ?error 175    \ misuse of <Dim
  483. \    ^class DFA 2+ c! ;
  484.  
  485. \ ( index -- addr ) ( dlen ^base -M- dlen ^base )  range check
  486. : ?Range    dup 0< >R range? R> or ClassErr" 129  ;
  487.  
  488. \ ( index -- addr )  Return pointer to indexed  element #
  489. : ^Elem
  490.     ?Class    RangeCheck
  491.     IF Compile ?range  THEN
  492.     Compile (^elem)   ;  Immediate
  493.  
  494. \ An object's base addr is always on top of mstack
  495. Create ^base    \ make code word alias
  496.     'Code copym here cfa !
  497.  
  498. \ length does not include cfa
  499. \ ( -- objlen )  compute total length of object
  500. \ - requires obj addr on mstack
  501. : objlen
  502.     copym @dlen copym ^dlen 2+ w@ -dup
  503.     IF idxBase 2- w@ * + 4+ THEN ;
  504.  
  505. \ Define  class init routine
  506. :F classInit    classinit: newObject   ;F
  507.  
  508. \ ( ^ivarLfa -- ) ( ivarOffs -M- )
  509. getSelect classInit: Constant initID
  510. :F initIvar
  511.     initID swap 8+    \ ( selID ivPfa )
  512.     dup cfa @        \ non-0 ^class?
  513.     IF  Find-Method cfa swap W@    ( 0cfa ivOffs )
  514.         copym newObject + +        ( 0cfa ^data )
  515.         swap execute            \ execute the 0cfa
  516.     ELSE  2drop        \ don't try to init Self or Super
  517.     THEN   ;F
  518.  
  519. \ clean up class compiler data on an Abort
  520. ' ;class cfa -> abortVec
  521.  
  522. \ dump will be in the Util module
  523. Forward dmp
  524.  
  525. \ install object builder
  526. ' (build) cfa -> bldvec
  527.  
  528. \ ( -- )  error if object is not indexed
  529. : ?ixObj
  530.     copym  4- @  ?IsClass not swap
  531.     dfa 2+ w@ 0= or classErr" 130 ;
  532.  
  533. : ?ixRange   ?IxObj  ?range  ;
  534. 'c ?ixRange vect ?idx
  535.  
  536. : +range  'c ?ixRange -> ?idx  ;
  537. : -range  'c null -> ?idx ;    \ no range checking
  538.  
  539. :CLASS Object  <Super Meta
  540.  
  541.     :M  AT:    ?idx  At4    ;M   ( index -- val )
  542.     :M  TO:    ?Idx  (^elem) !    ;M   ( val Index -- )
  543.     :M  +TO:   ?idx  ++4   ;M   ( incVal index -- )
  544.     :M  ^ELEM: ?Idx   ^elem        ;M   ( index -- addr )
  545.  
  546.     \ Leave max #elements for array
  547.     :M  LIMIT: ?ixObj limit  ;M    ( -- limit )
  548.  
  549.     \ ( e0 e1... en -- )  indexed PUT: loads array from stack
  550.     :M  PUT:   ?ixObj limit 0
  551.         DO   limit i- 1- (^elem) !  LOOP   ;M
  552.     \ ( -- e0 e1 ...en)  Indexed GET: places elements on stack
  553.     :M  GET:   ?ixObj limit 0 DO i at4  LOOP ;M
  554.  
  555.     :M  CLASS: copym  cfa  @  ;M    \  non-IX - leave class ptr
  556.  
  557.     \ ( -- addr len )  leave class name string for object
  558.     :M  WIDTH: ?ixObj  idxBase  4-  W@  ;M    \ IX - element size for array
  559.  
  560.     \ ( value -- )  Fill all elements with a value
  561.     :M  FILL:  limit 0 DO  dup i to: self     LOOP drop   ;M
  562.  
  563.     \ ( -- )  Indexed Clear: erases indexed area
  564.     :M  CLEAR:  idxBase  Width: self Limit: Self * Erase ;M
  565.  
  566.     :M  ABS:       (abs)   ;M    \  Absolute copy of mstack
  567.     :M  ADDR:      copym   ;M
  568.  
  569.     \ ( -- addr )  Leave addr of 0th indexed element
  570.     :M  IXADDR:    idxBase   ;M
  571.  
  572.     \ ( -- len )  Return total length of object
  573.     :M  LENGTH:    objlen      ;M
  574.     :M  PRINT:     copym objlen dmp ;M
  575.     :M  DUMP:      print: self  ;M    \ alias for Print:
  576.     :M  CLASSINIT:    ;M    \ null method for object init
  577.  
  578. ;CLASS
  579.  
  580. \ Bytes is used as the allocation primitive for basic classes
  581. : BYTES  ?Class  ' Object <Var  ^Class Dfa W+!  ;
  582.  
  583. \ define code words to get and set handle sizes
  584. \ ( handle size -- RC )  set handle size with condition code
  585. Create setHSize
  586.     popD0
  587.     popA0
  588.     $ a024 w,    \ call SetHandleSize
  589.     pushD0
  590.     next,
  591.  
  592. \ ( handle -- size )  get handle size
  593. Create getHSize
  594.     popA0
  595.     $ a025 w,    \ call GetHandleSize
  596.     pushD0
  597.     next,
  598.  
  599. <" Struct
  600.